Object-oriented programming makes it difficult to extend data that is encapsulated by instances of existing classes. Whenever a certain application of a given class would require additional data, such as additional fields, the most basic solution is to engage in class inheritance so that an extended class can be provided instead. The application must then be careful about using the new subclass rather than the original base class. This may be impractical since the application has often no control over the creation of instances. Furthermore, there is a good chance that several requirements make it impossible to favor a specific subclass.
Open-class mechanisms (such as partial classes in programming frameworks or introductions in aspect-oriented programming) have been proposed to add any sort of members (including fields) to existing classes. These methods are normally restricted to design-time class extension. Those few approaches that allow for run-time class extension are again too restricted. First, these approaches tend to be restricted to dynamically typed languages. And second, they tend to allow for extra methods but not for extra fields (i.e., data).
Design patterns have been invented to remedy some of these problems. For instance, the decorator design patterns has been proposed (in various forms) to enable the decoration of existing instances by behavior and data. Also, the factory pattern has been proposed to avoid commitment to class-specific constructors in code. However, even the combination of these two patterns (and other standard design patterns) cannot provide unanticipated extension of instances by data. Moreover, the resulting designs suffer from serious limitations or defects, namely, object schizophrenia (object schizophrenia results when the state and/or behavior of what is intended to appear as a single object is actually broken-up into several objects, each of which has its own object identity). In particular, the design must be globally ruled by the sometimes inconvenient design patterns, and base objects and extended objects carry different object identities, which often leads to incorrect or inflexible solutions.
There is one known general technique for instance annotation, but it is prohibitively expensive in practice, hence it is hardly used. It may maintain a mapping from instances to annotations by means of a dictionary. The obvious problem with this approach is that the dictionary gets potentially congested, as the number of instances grows. Yet another problem with this approach is that base data and extended data are exposed in very different ways. In particular, the status of the extended data in a dictionary will be exposed to any client code that relies on the relevant objects to carry such additional data.
There are many refinements of the ideas mentioned above, but none of them satisfies a requirement for a general, efficient, non-intrusive, robust, statically type-safe, easy-to-use technique for instance annotation. Thus, to address at least the above mentioned problems, various solutions are disclosed herein.